/* eslint-disable @typescript-eslint/no-explicit-any */
import { ref, reactive, computed } from 'vue';
import { QTableProps, date } from 'quasar';

import { DEFAULT_PAGE_SIZE } from './useQuery';

interface Pagination {
  sortBy?: string | null;
  descending?: boolean;
  page?: number;
  rowsPerPage?: number;
  rowsNumber?: number;
}

export const useTable = () => {
  //生成列配置
  const tc = (field: string, label: string, width = 0, other?: 'left' | 'right' | 'center' | Partial<TableColumn>) => {
    const col: TableColumn = { name: field, label, field, align: 'left', sortable: true };

    if (field === 'action') {
      col.headerStyle = 'padding-left:12px;min-width:100px';
      col.sortable = false;
    }

    if (other) {
      if (typeof other === 'string') {
        col.align = other;
      } else {
        Object.assign(col, other);
      }
    }

    col.width = width;
    if (width && width > 0) {
      const widthStyle = `min-width:${width}px`;
      col.style = col.style ? col.style + ';' + widthStyle : widthStyle;
    }

    return col;
  };

  const loading = ref(false);
  const rows = ref<any[]>([]);
  const selected = ref<any[]>([]);

  const { formatDate } = date;
  const formatter = {
    date: (v: Date | string) => formatDate(v, 'YYYY-MM-DD'),
    dateTime: (v: Date | string) => formatDate(v, 'YYYY-MM-DD HH:mm'),
    boolean: (v: boolean) => (v ? '是' : '否'),
    disabled: (v: boolean) => (v ? '作废' : '正常'),
  };
  const hasSelected = computed(() => selected.value.length > 0);
  return { tc, loading, rows, selected, hasSelected, formatter };
};

export const useTableServer = (fetchData: (query: PageQuery) => Promise<PageResult<unknown>>, query: PageQuery, idField: string) => {
  const { tc, formatter } = useTable();

  const tableOptions = reactive<QTableProps>({
    rowKey: idField,
    loading: false,
    rows: [],
    pagination: { page: query.pageNo, rowsPerPage: query.pageSize, rowsNumber: 0 },
    'onUpdate:pagination': updatePagination,
    selected: [],
    'onUpdate:selected': updateSelected,
    onRequest,
  });

  function updateSelected(selected: readonly any[]) {
    tableOptions.selected = [...selected];
  }
  function updatePagination(n: Pagination) {
    tableOptions.pagination!.page = n.page;
    tableOptions.pagination!.rowsPerPage = n.rowsPerPage;
    tableOptions.pagination!.sortBy = n.sortBy;
    tableOptions.pagination!.descending = n.descending;
  }

  function onRequest(props: { pagination: Pagination }) {
    const { pagination } = props;
    query.pageNo = pagination.page ?? 1;
    query.pageSize = pagination.rowsPerPage ?? DEFAULT_PAGE_SIZE;

    query.sortBy = pagination.sortBy
      ? [{ sortField: pagination.sortBy, sortType: pagination.descending === true ? 'desc' : 'asc' }]
      : undefined;

    handleQuery(false);
  }

  // 查询数据
  function handleQuery(resetPage = true) {
    if (resetPage) {
      query.pageNo = 1;
    }
    tableOptions.loading = true;
    fetchData(query)
      .then((data) => {
        tableOptions.rows = data.dataList;
        tableOptions.pagination!.rowsNumber = data.totalCount;

        tableOptions.pagination!.page = query.pageNo;
        tableOptions.pagination!.rowsPerPage = query.pageSize;
        tableOptions.pagination!.sortBy = query.sortBy?.length ? query.sortBy[0].sortField : undefined;
        tableOptions.pagination!.descending = query.sortBy?.length ? query.sortBy[0]?.sortType === 'desc' : undefined;

        // 查询后清空选择项
        tableOptions.selected = [];
      })
      .finally(() => (tableOptions.loading = false));
  }

  // 获取选中的ID
  const hasSelected = computed(() => tableOptions.selected?.length ?? 0 > 0);
  const selectedIds = computed(() => tableOptions.selected?.map((a) => a[idField] as IdType));

  // 计算序号
  const getRowIndex = (index: number) => index + 1 + (query.pageNo - 1) * query.pageSize;

  // 返回数据
  return { tc, formatter, tableOptions, handleQuery, hasSelected, selectedIds, getRowIndex };
};
